//PITCH PROGRAM
//CLASS: AI_PLAYER
//	-functions to set up computer panels, bid, 
//	and play cards
//BY: ALEX TRACY
public class AI_Player extends Player
{
	AI_Bid bid = new AI_Bid();
	
	public AI_Player(int i)
	{
		super(i);
	}//End Constructor
	
	//GENERAL FUNCTIONS//
	
	//set cards in hand to back of card image
	public void initPanel()
	{
		for (int i = 0 ; i < this.getHand().length;i++)
		{
			setCardImage(i, Card.getCardBack(getCard(i)));
		}
	}//End initPanel	
	
	//return false for AI Player
	public boolean isHuman()
	{
		return false;
	}//End isHuman
	
	
	//BID FUNCTIONS//
	
	//determine bid suit by calling AI_BID object bid to
	//return the best suit
	public void determineBidS()
	{
		super.setBidS(bid.getBidSuit(getHand()));
	}//End determineBidS
	
	//determine bid by calling AI_BID object bid to
	//return the best bid 
	public void determineBid(int high)
	{
		if (bid.getBidValue(getHand()) > high )
		{
			setBid(bid .getBidValue(getHand()));
		}
		else
		{
			setBid(0);
		}
	}//end determineBid

	//PLAY FUNCTIONS//
	
	//determine turn of player, if player is first throw highest available card,
	//if player is second call normalplayroutine to determine card to throw,
	//if player is third call thirdthrowroutine to determine card to throw,
	//if player is last call lastthrowroutine to determine card to throw
	//play whatever card has been specified by the switch
	public int play(int[] played,int led,int trump,int turn, 
			int boss,boolean jackOut,boolean twoOut, int hN)
	{
		int toPlay = -1;			
		
		switch(turn)
		{
		case 0: 
			toPlay = getHighestCard(trump);
			break;
		case 1:
			toPlay = normalPlayRoutine(trump,led,played);
			break;
		case 2:
			toPlay = thirdToThrowRoutine(trump,led,played,boss,twoOut);
			break;
		case 3:
			toPlay = lastToThrowRoutine(trump,led,played,boss);
			break;
		}
	
		return playCard(toPlay);
	}//End Play
	
	//if score points are out call tryToTakeScorePoints
	//else if game points are out call tryToTakeGamePoints
	//else play worst card
	private int normalPlayRoutine(int t, int l, int p[])
	{
		if (scorePointsPlayed(t,p))
		{	
			return tryToTakeScorePoints(t,l,p);
		}
		else if ( gamePointsPlayed(l,p) )
		{
			return tryToTakeGamePoints(t,l,p);
		}
		else
		{
			return playWorstCard(t,l);
		}
		
	}//End normalPlayRoutine
	
	//if partner played the boss call partnerPlayedBoss
	//else if the two is not out block for two
	//else call normalPlayRoutine
	private int thirdToThrowRoutine(int t, int l, int p[],int b,
			boolean tO)
	{
		if (p[getPartnerIndex()] == b)
		{	
			return partnerPlayedBoss(t,l,p);
		}
		
		else if (tO == false && trumpLeft(t) && 
				!trumpPlayed(t,p))
		{
			return getLowest(t);
		}
		else
		{
			return normalPlayRoutine(t,l,p);
		}
	}//End thirdToThrowRoutine
	
	//if no trump has been played and have two throw the two
	//else if no trump has been played and have jack throw the jack
	//else if partner played boss call partnerPlayedBoss
	//else call normalPlayRoutine
	private int lastToThrowRoutine(int t, int l, int p[],int b)
	{
		if (trumpPlayed(t,p) == false && haveTwo(t))
		{
			return returnTwo(t);
		}
		else if (trumpPlayed(t,p) == false && haveJack(t))
		{
			if (returnJack(t) != b)
			{
				return returnJack(t);
			}
		}
		else if (p[getPartnerIndex()] == b)
		{
			return partnerPlayedBoss(t,l,p);
		}
		return normalPlayRoutine(t,l,p);
	}//end lastToThrow	
	
	
	//try to feed partner points if partner has played the highest
	//card that can possibly be played, if player has the 2 play that
	//otherwise if player has the jack play that, otherwise if player
	//has the 10 play that, otherwise if trump left play the lowest trump
	//if no trump left try to give game points, if no game points left
	//throw worst card
	private int partnerPlayedBoss(int t, int l,int p[])
	{
		if (trumpLeft(t))
		{
			if (haveTwo(t))
			{
				return returnTwo(t);
			}
			else if (haveJack(t))
			{
				return returnJack(t);
			}
			else if (haveTen(t))
			{
				return returnTen(t);
			}
			else 
			{
				return getLowest(t);
			}
		}	
		else if (gamePointsLeft())
		{
			return returnHighestOffGamePoint();
		}
		else 
		{
			return playWorstCard(t,l);
		}
	
	}//End partnerPlayedBoss
	
	//try to take score points, if not possible to take score points
	//return worst card
	private int tryToTakeScorePoints(int t, int l , int p[])
	{
		if (getHighest(t) > getHighestPlayed(t,l,p) )
		{
			return playCard(getHighestCard(t));
		}
		else
		{
			return playWorstCard(t,l);
		}	
	}//end tryToTakeScorePoints
	
	//try to take game points, if not possible to take game points
	//return worst card
	private int tryToTakeGamePoints(int t, int l, int p[])
	{
		if (trumpPlayed(t,p) == false)
		{
			if (getHighest(l) > getHighestPlayed(t,l,p))
			{
				return getHighest(l);
			}
		}	
		return playWorstCard(t,l);
	}
	
	//plays the worst card possible, if trump was led and player
	//has trump left return the lowest trump, else if cards are left
	//in the suit led return the lowest one, else if player has
	//off cards left return the worst one, otherwise return the lowest
	//trump
	private int playWorstCard(int t, int l)
	{
		if ( l == t && trumpLeft(t))
		{
			return getLowestTrump(t);
		}	
		else if (getLowest(l) != -1)
		{
			return getLowest(l);
		}
		else if (getLowestOffCard(t) != -1)
		{
			return getLowestOffCard(t);
		}
		else
		{
			return getLowestTrump(t);
		}
	}//end playWorstCard
	
	
	//FUNCTIONS TO READ OWN CARDS//
	
	//return highest possible card, if trump left
	//return highest trump, else return highest
	//card of other other suits
	private int getHighestCard(int t)
	{
		int highest = -1;
		int highestFace = -1;
		highest = getHighest(t);
		if (highest == -1)
		{
			for (int i = 0; i < this.getHand().length; i++)
				if (Card.getFace(this.getCard(i)) >
				highestFace)
				{
					highest = getCard(i);
					highestFace = Card.getFace(
							this.getCard(i));
				}
		}
		return highest;
	}//end getHighestCard
	

	//get highest card of suit specified
	private int getHighest(int s)
	{
		int highest = -1;
		for (int i = 0; i < this.getHand().length;i++)
		{	if ( Card.getSuit(this.getCard(i)) == s 
				&& this.getCard(i) > highest )
			{
					highest = this.getCard(i);
			}
		}
		return highest;
	}//End getHighest
	
	//return lowest trump , if possible play card higher than
	//2, if not return the two
	private int getLowestTrump(int t)
	{
		int lowest = -1;
		for (int i = 0; i < this.getHand().length;i++)
		{
			if ( Card.getSuit(this.getCard(i)) == t )
			{
				if (!Card.isJack(getCard(i)) && 
						!Card.isDeuce(getCard(i)))
				{
					if (getCard(i) == -1)
					{
						
					}
					else if (lowest == -1)
					{
						lowest = this.getCard(i);
					}
					else if ( this.getCard(i) 
							< lowest )
					{
					lowest = this.getCard(i);
					}
				}
			}	
		}
		if (lowest == -1)
			lowest = returnTwo(t);
		if (lowest == -1)
			lowest = returnJack(t);
		return lowest;
	}//End getLowest
	
	//get lowest card of suit specified
	private int getLowest(int l)
	{
		int lowest = -1;
		for (int i = 0; i < this.getHand().length;i++)
		{
			if ( Card.getSuit(this.getCard(i)) == l )
			{
				if (getCard(i) == -1)
				{
					
				}
				else if (lowest == -1)
				{
					lowest = this.getCard(i);
				}
				else if ( this.getCard(i) < lowest )
				{
					lowest = this.getCard(i);
				}
			}
		}	
		return lowest;
	}//End getLowest
	
	//get lowest card that is not trump
	private int getLowestOffCard(int t)
	{
		int lowest = -1;
		int lowestFace = -1;
		for (int i = 0; i < this.getHand().length; i++)
		{
			if (Card.getSuit(this.getCard(i)) != t)
			{
				if (getCard(i) == -1)
				{
					
				}
				else  if (lowest == -1)
				{
					lowest = this.getCard(i);
					lowestFace = Card.getFace(
							this.getCard(i));
				}
				else if (Card.getFace(
						this.getCard(i)) < lowestFace)
				{
					lowest = this.getCard(i);
					lowestFace = Card.getFace(
							this.getCard(i));
				}
			}
		}	
		return lowest;
	}//end getLowest
	
	//return true if trump is left otherwise return false
	private boolean trumpLeft(int t)
	{
		for(int i = 0 ; i < this.getHand().length ; i++)
		{
			if (getCard(i) != -1 && 
					Card.getSuit(this.getCard(i)) == t)
			{
				return true;
			}
		}
		return false;
	}//end trumpLeft
	
	//check if player has the two of trump
	private boolean haveTwo(int t)
	{
		for (int i = 0 ; i < getHand().length;i++)
		{	if (Card.getSuit(getCard(i)) == t &&
				Card.isDeuce(getCard(i)))
			{
				return true;
			}
		}
		return false;
	}//end haveTwo

	//check for jack of trump 
	private boolean haveJack(int t)
	{
		for (int i = 0 ; i < getHand().length;i++)
		{	if (Card.getSuit(getCard(i)) == t && 
				Card.isJack(getCard(i)))
			{
				return true;
			}
		}
		return false;
	}//end haveJack
	
	//check if player has 10 in suit specified
	private boolean haveTen(int s)
	{
		for (int i = 0 ; i < getHand().length ; i++)
		{
			if (Card.getSuit(getCard(i)) == s && 
					Card.isTen(getCard(i)))
			{
				return true;
			}
		}
		return false;
	}//End haveTen
	
	//check if player has game points left
	//return true if they do otherwise return
	//false
	private boolean gamePointsLeft()
	{
		for (int i = 0 ; i < getHand().length ; i++)
		{	if (Card.getFace(getCard(i)) >= 8 )
			{
				return true;
			}
		}
		return false;
	}//end gamePointsLeft
	
	//if player has the two of trump return it
	private int returnTwo(int t)
	{
		if (haveTwo(t))
		{
			for (int i = 0 ; i < getHand().length ; i++)
			{
				if (Card.getSuit(getCard(i)) == t && 
						Card.isDeuce(getCard(i)))
				{
					return getCard(i);
				}
			}
		}
		return -1;
	}//end returnTwo
	
	//return jack of trump if player has it 
	private int returnJack(int t)
	{
		if (haveJack(t))
		{
			for (int i = 0 ; i < getHand().length ; i++)
			{
				if (Card.getSuit(getCard(i)) == t && 
						Card.isJack(getCard(i)))
				{
					return getCard(i);
				}
			}
		}
		return -1;
	}//end returnJack
	
	
	//if player has 10 of suit specified return it
	private int returnTen(int s)
	{
		if (haveTen(s))
		{
			for (int i = 0 ; i < getHand().length; i++)
			{
				if (Card.getSuit(getCard(i)) == s && 
						Card.isTen(getCard(i)))
				{
					return getCard(i);
				}
			}
		}
		return -1;
	}//end returnTen
	
	//return the highest game point possible
	//10 being the highest then A to J
	private int returnHighestOffGamePoint()
	{
		int high = -1;
		for (int i = 0 ; i < getHand().length; i ++)
		{
			if (Card.getFace(getCard(i)) >= 8)
			{
				if ( Card.isTen(getCard(i)) )
				{
					high = getCard(i);
					break;
				}
				else if ( Card.getFace(getCard(i)) > Card.getFace(high) )
				{
					high = getCard(i);
				}
			}	
		}
		return high;
	}//end returnHighestOffGamePoint
	
	
	//FUNCTIONS TO READ OTHER PLAYERS CARDS
	
	//check if two has been played this hand return
	//true if it has otherwise return false
	private boolean checkForTwo(int t, int p[])
	{
		for (int i = 0 ; i < p.length ; i++)
		{	if (Card.getSuit(p[i]) == t && Card.isDeuce(p[i]))
			{
			return true;
			}
		}
		return false;
	}//end checkForTwo
	
	//check if jack has been played this hand return
	//true if it has otherwise return false
	private boolean checkForJack(int t, int p[])
	{
		for (int i = 0 ; i < p.length ; i++)
		{	if (Card.getSuit(p[i]) == t && Card.isJack(p[i]))
			{
			return true;
			}
		}
		return false;
	}//end checkForJack
	
	//check if either a jack or 2 has been played
	//return true if they have been played
	//false if they haven't
	private boolean scorePointsPlayed(int t, int p[])
	{
		if (checkForTwo(t,p) || checkForJack(t,p))
		{
			return true;
		}
		else
		{
			return false;
		}
	}//End scorePointsPlayed
	
	//if a trump has been played return true
	//otherwise return false
	private boolean trumpPlayed(int t,int p[])
	{
		for ( int i = 0 ; i < p.length ; i++)
		{
			if ( Card.getSuit(p[i]) == t )
			{
				return true;
			}
		}	
		return false;
	}//End trumpPlayed
	
	//get highest card played so far
	//if trump has been played return the highest trump,
	//otherwise return the highest of the suit led
	private int getHighestPlayed(int t,int l,int p[])
	{
		int highest = -1;
		for ( int i = 0 ; i < p.length ; i++)
		{
			if ( Card.getSuit(this.getCard(i)) == t )
			{	
				if (this.getCard(i) > highest)
				{	
					highest = this.getCard(i);
				}
			}
		}
		if (highest != -1)
		{	
			for (int i = 0; i < p.length; i++)
			{
				if (Card.getSuit(this.getCard(i)) == l)
				{
					if (this.getCard(i) > highest)
					{
						highest = this.getCard(i);
					}
				}	
			}
		}
		return highest;
	}//end getHighestPlayed

	//return true if game points have been played
	//false if they have not
	private boolean gamePointsPlayed(int l, int p[])
	{
		for (int i = 0 ; i < p.length ; i++ )
		{	if (Card.getFace(p[i]) >= 8 )
			{
				return true;
			}
		}
		return false;
	}//End gamePointsPlayed
	
}//End AI_Player
